package com.dongman.scrapy;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dongman.mapper.NovelDao;
import com.dongman.model.ChapterPic;
import com.dongman.model.Constants;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.jsoup.Connection;
import org.jsoup.nodes.Document;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

@Log4j2
public class CrawlUtil {

    private static List<String> userAgents = new ArrayList<>();

    static {
        userAgents.add("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36");
        userAgents.add("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1");
        userAgents.add("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36");
        userAgents.add("Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50");
        userAgents.add("Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11");
        userAgents.add("Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Maxthon 2.0)");
        userAgents.add("Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SE 2.X MetaSr 1.0; SE 2.X MetaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)");
        userAgents.add("Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)");
        userAgents.add("Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)");
        userAgents.add("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;");
    }

    /***
     * 随机一个请求头
     * @return
     */
    public static String getUserAgent() {
        int index = new Random().nextInt(10); // 随机获取一个0-9的整数作为索引
        return userAgents.get(index);
    }

    /**
     * 超时重新连接
     * @param conn
     * @param tryTimes
     * @return
     */
    public static Document connectOneMoreTimes(Connection conn, int tryTimes){
        Document document = null;
        boolean isContinue = true;
        int thisTryTimes = 0;
        while(isContinue && thisTryTimes < tryTimes){
            try {
                try {
                    document = conn.get();
                    isContinue = false;
                } catch (Exception e) {
                    System.out.println("   超时之后，重新尝试连接....." + thisTryTimes + "，次");
                    Thread.sleep(Constants.sleepSeconds);
                    document = conn.get();
                    thisTryTimes++;
                }
            }catch (Exception e) {
                System.out.println("获取图片失败");
                e.printStackTrace();
            }
        }
        return document;
    }

    /**
     * 自动登录, 获取请求的cookie
     * @param username
     * @param password
     * @return
     */
    public static String login(String username, String password) {
        String url = "https://www.qiteman.com/index.php/api/user/login";
        HttpClient client = new HttpClient();
        PostMethod postMethod = new PostMethod(url);

        String userAgent = "User-Agent";
        String contentType = "content-type";
        //添加请求头
        postMethod.addRequestHeader(userAgent, CrawlUtil.getUserAgent());
        postMethod.addRequestHeader(contentType, "application/x-www-form-urlencoded; charset=UTF-8");
        //添加请求参数
        postMethod.addParameter("name", username);
        postMethod.addParameter("pass", password);
        postMethod.addParameter("islog", "1");
        postMethod.addParameter("pcode", "");

        try {
            client.executeMethod(postMethod);
            String res = postMethod.getResponseBodyAsString();
            Header[] headers = postMethod.getResponseHeaders();
            JSONObject dataRes = JSONObject.parseObject(res);
            System.out.println(dataRes);
            return headers[5].getValue();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            postMethod.releaseConnection();
        }
        return "";
    }

    /**
     * 将漫画图片爬取到本地
     * @param novelName
     * @param chapterName
     * @param chapterPics
     */
    public static void savePicToBase(String novelName, String chapterName, List<ChapterPic> chapterPics, String picSavePath, NovelDao novelDao) {

        //这些格式不能创建文件夹,去掉
        novelName = novelName.replace("/", " ");
        novelName = novelName.replace("\\", " ");
        novelName = novelName.replace(":", " ");
        novelName = novelName.replace("|", " ");
        novelName = novelName.replace("?", " ");
        novelName = novelName.replace("*", " ");
        novelName = novelName.replace(">", " ");
        novelName = novelName.replace("...", " ");
        novelName = novelName.replace("<", " ").trim();


        chapterName = chapterName.replace("/", " ");
        chapterName = chapterName.replace("\\", " ");
        chapterName = chapterName.replace(":", " ");
        chapterName = chapterName.replace("|", " ");
        chapterName = chapterName.replace("?", " ");
        chapterName = chapterName.replace("*", " ");
        chapterName = chapterName.replace(">", " ");
        chapterName = chapterName.replace("...", " ");
        chapterName = chapterName.replace("<", " ").trim();

        String folder = picSavePath + "/" + novelName + "/" + chapterName + "/";

        File file = new File(folder);

        if (!file.exists()) {
            file.mkdirs();
        }

        for (ChapterPic chapterPic: chapterPics) {
            String picUrl = chapterPic.getPicLink();
            System.out.println("start down pic::" + picUrl);
            URL url1;
            URLConnection uc = null;
                try{
                    url1 = new URL(picUrl);
                    uc = url1.openConnection();
                    uc.setConnectTimeout(30000);
                    uc.setReadTimeout(30000);
                }catch (Exception e) {
                    System.out.println("超时，继续下载...1");
                    try{
                        url1 = new URL(picUrl);
                        uc = url1.openConnection();
                        uc.setConnectTimeout(30000);
                        uc.setReadTimeout(30000);
                    }catch (Exception e1){
                        System.out.println("超时，继续下载...2");
                        try{
                            url1 = new URL(picUrl);
                            uc = url1.openConnection();
                            uc.setConnectTimeout(30000);
                            uc.setReadTimeout(30000);
                        }catch (Exception e2){

                        }
                    }
                }
            try {
                InputStream inputStream = uc.getInputStream();
                String picName = folder + chapterPic.getBasePicName();
                System.out.println("down pic done::" + picName + "," + picUrl);
                FileOutputStream out = new FileOutputStream(picName);
                int j;
                while ((j = inputStream.read()) != -1) {
                    out.write(j);
                }
                inputStream.close();
                chapterPic.setIsDownToLocal(Constants.DownToLocal);
                Thread.sleep(500);
                novelDao.updateChapterPic(chapterPic);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 根据链接请求VIP章节的图片
     * @param chapterLink
     * @param cookie
     * @param username
     * @param password
     * @return
     */
    public static List<ChapterPic> getChapterPicsByLink(String chapterLink, String cookie, String username, String  password) {
        String[] sspls = chapterLink.split("/");
        String chapterId = sspls[sspls.length - 1].replace(".html", "");

        String url = "https://www.qiteman.com/index.php/api/comic/isbuy";
        HttpClient client = new HttpClient();
        PostMethod postMethod = new PostMethod(url);

        String userAgent = "User-Agent";
        String contentType = "content-type";
        String cookiename = "cookie";
        //添加请求头
        postMethod.addRequestHeader(userAgent, CrawlUtil.getUserAgent());
        postMethod.addRequestHeader(contentType, "application/x-www-form-urlencoded; charset=UTF-8");
        postMethod.addRequestHeader(cookiename, cookie);
        //添加请求参数
        postMethod.addParameter("id", chapterId);

        List<ChapterPic> chapterPics = new ArrayList<>();
        JSONObject dataRes;
        try {
            client.executeMethod(postMethod);
            String res = postMethod.getResponseBodyAsString();
            dataRes = JSONObject.parseObject(res);
            String code = dataRes.getString("code");
            if (!"1".equals(code)) {
                /*// 尝试第一次登录，可能是登录过期，导致没有登录
                String cookieRes = CrawlUtil.login(username, password);
                postMethod.addRequestHeader(cookiename, cookieRes);

                client.executeMethod(postMethod);
                String res2 = postMethod.getResponseBodyAsString();
                dataRes = JSONObject.parseObject(res2);
                String code2 = dataRes.getString("code");
                if (!"1".equals(code2)) {
                    //todo 提醒登录已过期
                    throw new RuntimeException("登录已过期");
                }*/
                return chapterPics;
            }
            JSONArray data = JSONArray.parseArray(dataRes.getString("pic"));
            for (int i = 0; i < data.size(); i++) {
                JSONObject one = (JSONObject) data.get(i);
                System.out.print(one);
                String chapterPicId = one.getString("id");
                Date createDate = new Date();
                Date updateDate = new Date();
                String basePicName = chapterPicId + ".jpg";
                String chapterPicUrl = one.getString("img");
                ChapterPic chapterPic = new ChapterPic(
                        chapterPicId, createDate, updateDate, chapterPicUrl, basePicName, chapterId, "0"
                );
                chapterPic.toString();
                System.out.print(chapterPic);
                chapterPics.add(chapterPic);
            }
        } catch (IOException e) {
            System.out.print("爬取小说：" + chapterId + "，失败");
        } finally {
            postMethod.releaseConnection();
        }
        return chapterPics;
    }

    public static void main(String[] args) {
        login("17798211703",
                "qt101010");
    }
}
